package com.itheima.appserver.service;

import cn.hutool.core.bean.BeanUtil;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.appserver.interceptor.UserThreadLocal;
import com.itheima.commons.model.domain.Title;
import com.itheima.commons.model.domain.UserInfo;
import com.itheima.commons.model.domain.UserLoginRecord;
import com.itheima.commons.model.mongo.Comment;
import com.itheima.commons.model.mongo.Publish;
import com.itheima.commons.model.mongo.Video;
import com.itheima.commons.model.vo.*;
import com.itheima.dubbo.interfaces.*;
import org.bson.types.ObjectId;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @Author: lqTao
 * @Date: 2021/12/16 18:16
 */
@Service
public class ManageService {

    @Reference
    UserInfoApi userInfoApi;
    @Reference
    CommentApi commentApi;
    @Reference
    PublishApi publishApi;

    @Reference
    AlbumApi albumApi;
    @Reference
    UserFreezeApi userFreezeApi;
    @Reference
    VideoApi videoApi;
    @Reference
    UserLoginRecordApi userLoginRecordApi;


    //获取该用户的视频列表
    public PageResult videoList(Integer page, Integer pageSize, String sortProp, String sortOrder, Integer uid) {

        //根据用户id查询所有的视频
        List<Video> videoList = videoApi.queryVideoListByUid(uid);
        //拼凑
        List<VideoManageVo> videoManageVos = getVideoVo(videoList);

        //起始页
        int startIndex = (page - 1) * pageSize;
        //每页容量
        int endIndex = Math.min(startIndex + pageSize, videoList.size());
        videoManageVos = getSortVideoVo(videoManageVos, sortProp, sortOrder, startIndex, endIndex);


        return new PageResult(startIndex + 1, endIndex, Convert.toLong(videoList.size()), videoManageVos);
    }

    //获取该用户的日志列表
    public PageResult logsList(Integer page, Integer pageSize, String sortProp, String sortOrder, String type, Integer uid) {
        //根据用户的id获取相对应的日志信息
        List<UserLoginRecord> logsList = userLoginRecordApi.queryLogsListByUserId(page, pageSize, sortProp, sortOrder, uid);
        //拼凑UserLogsVo
        List<UserLogsVo> userLogsVoList = getUserLogsVo(logsList);
        //统计该用户的信息的总条数
        Long count = userLoginRecordApi.countLogsSize(uid);
        return new PageResult(page, pageSize, count, userLogsVoList);
    }

    //获取该用户某一条朋友圈的评论列表
    public PageResult commentsList(Integer page, Integer pageSize, String sortProp, String sortOrder, ObjectId id) {
        PageResult pageResult = commentApi.queryCommentList(id.toString(), page, pageSize);
        List<Comment> items = (List<Comment>) pageResult.getItems();
        List<CommentsManageVo> commentsManageVos = new ArrayList<>();
        for (Comment item : items) {
            CommentsManageVo commentsManageVo = new CommentsManageVo();
            commentsManageVo.setId(item.getId().toHexString());
            UserInfo userInfo = userInfoApi.findUserInfoByUserId(item.getUserId());
            commentsManageVo.setNickname(userInfo.getNickName());
            commentsManageVo.setUserId(item.getUserId().toString());
            commentsManageVo.setContent(item.getContent());
            commentsManageVo.setCreateDate(item.getCreated());
            commentsManageVos.add(commentsManageVo);
        }
        return new PageResult(page, pageSize, Convert.toLong(items.size()), commentsManageVos);
    }


    //拼凑List<UserLogsVo>
    private List<UserLogsVo> getUserLogsVo(List<UserLoginRecord> logsList) {
        List<UserLogsVo> userLogsVos = new ArrayList<>();
        for (UserLoginRecord loginRecord : logsList) {
            UserLogsVo logsVo = new UserLogsVo();
            logsVo.setId(Convert.toInt(loginRecord.getId()));
            logsVo.setLogTime(Convert.toLong(loginRecord.getLogtime()));
            logsVo.setPlace(loginRecord.getPlace());
            logsVo.setEquipment(loginRecord.getEquipment());
            userLogsVos.add(logsVo);
        }
        return userLogsVos;
    }


    //拼凑List<VideoManageVo>
    private List<VideoManageVo> getVideoVo(List<Video> videoList) {
        List<VideoManageVo> videoManageVos = new ArrayList<>();
        for (Video video : videoList) {
            int i = 1;
            VideoManageVo videoManageVo = new VideoManageVo();
            videoManageVo.setId(i);
            UserInfo userInfo = userInfoApi.findUserInfoByUserId(video.getUserId());
            videoManageVo.setNickname(userInfo.getNickName());
            videoManageVo.setUserId(Convert.toInt(video.getUserId()));
            videoManageVo.setCreateDate((video.getCreated()));
            videoManageVo.setVideoUrl(video.getVideoUrl());
            videoManageVo.setPicUrl(video.getPicUrl());
            videoManageVo.setReportCount(0);
            videoManageVo.setLikeCount(Convert.toInt(commentApi.queryCommentCount(video.getId().toString(), 1)));
            videoManageVo.setCommentCount(Convert.toInt(commentApi.queryCommentCount(video.getId().toString(), 2)));
            videoManageVo.setForwardingCount(0);
            videoManageVos.add(videoManageVo);
        }
        return videoManageVos;
    }

    //List<VideoManageVo>排序
    private List<VideoManageVo> getSortVideoVo(List<VideoManageVo> videoManageVos, String sortProp, String sortOrder, Integer startIndex, Integer endIndex) {
        //比较器
        Comparator<VideoManageVo> comparator = new Comparator<VideoManageVo>() {
            @Override
            public int compare(VideoManageVo o1, VideoManageVo o2) {
                if (sortOrder.equals("ascending")) {
                    //升序
                    switch (sortProp) {
                        //升序根据喜欢数排
                        case "likeCount": {
                            Integer lc1 = o1.getLikeCount();
                            Integer lc2 = o2.getLikeCount();
                            if (lc1 >= lc2) {
                                return 1;
                            } else {
                                return -1;
                            }
                        }
                        //升序根据喜欢数排
                        case "commentCount": {
                            Integer co1 = o1.getCommentCount();
                            Integer co2 = o2.getCommentCount();
                            if (co1 >= co2) {
                                return 1;
                            } else {
                                return -1;
                            }
                        }
                        case "createDate": {
                            Long cd1 = o1.getCreateDate();
                            Long cd2 = o2.getCreateDate();
                            if (cd1 >= cd2) {
                                return 1;
                            } else {
                                return -1;
                            }
                        }
                        default:
                            return 1;
                    }
                } else {
                    //降序
                    switch (sortProp) {
                        //降序根据喜欢数排
                        case "likeCount": {
                            Integer lc1 = o1.getLikeCount();
                            Integer lc2 = o2.getLikeCount();
                            if (lc1 < lc2) {
                                return 1;
                            } else {
                                return -1;
                            }
                        }
                        //降序根据喜欢数排
                        case "commentCount": {
                            Integer co1 = o1.getCommentCount();
                            Integer co2 = o2.getCommentCount();
                            if (co1 < co2) {
                                return 1;
                            } else {
                                return -1;
                            }
                        }
                        case "createDate": {
                            Long cd1 = o1.getCreateDate();
                            Long cd2 = o2.getCreateDate();
                            if (cd1 < cd2) {
                                return 1;
                            } else {
                                return -1;
                            }
                        }
                        default:
                            return 1;
                    }
                }
            }
        };
        return videoManageVos = CollUtil.sortPageAll(startIndex, endIndex, comparator, videoManageVos);
    }


//==============================================================================================================================

    /**
     * @param uid      用户id
     * @param page
     * @param pagesize
     * @param sortProp
     * @param sortOrder
     * @return
     */
    public PageResult messages(Long uid, Integer page, Integer pagesize, String sortProp, String sortOrder) {

        //通过用户id查询发布了哪些朋友圈
        List<Long> uids = new ArrayList<>();
        uids.add(uid);

        List<Publish> publishes = publishApi.queryPublishByUid(uids, page, pagesize,sortProp,sortOrder);
        if (ObjectUtil.isNull(publishes)) {
            //该用户没发朋友圈
            return new PageResult(page, pagesize, 0L, ListUtil.empty());
        }

        List<ManageVo> list = new ArrayList<>();
        for (Publish publish : publishes) {
            UserInfo userInfo = userInfoApi.findUserInfoByUserId(uid);
            ManageVo manageVo = getManageVo(uid, publish, userInfo);
            list.add(manageVo);
        }

        return new PageResult(page, pagesize, Convert.toLong(publishes.size()), list);
    }


    private ManageVo getManageVo(Long uid, Publish publish, UserInfo userInfo) {
        String publishId = Convert.toStr(publish.getId());
        ManageVo manageVo = new ManageVo();
        manageVo.setId(publishId);
        manageVo.setUserId(uid);
        manageVo.setNickname(userInfo.getNickName());
        manageVo.setUserLogo(userInfo.getLogo());
        manageVo.setCreateDate(publish.getCreated());
        manageVo.setText(publish.getText());


        manageVo.setState(Convert.toStr(publish.getStatus()));
        manageVo.setLikeCount(commentApi.queryCommentCount(publishId, 1));
        manageVo.setCommentCount(commentApi.queryCommentCount(publishId, 2));
        manageVo.setMedias(publish.getMedias());

        manageVo.setReportCount(0L);
        manageVo.setForwardingCount(0L);
        return manageVo;
    }


    public PageResult messagesList(String uid, Integer page, Integer pagesize, String sd, String ed, String state) {

        if (ObjectUtil.isNull(state)) {
            state = "3";
        }
        if (ObjectUtil.isNull(sd)) {
            sd = "-1";
        }
        if (ObjectUtil.isNull(ed)) {
            ed = "-1";
        }

        List<Long> userIds = new ArrayList<>();
        List<UserInfo> userInfos = new ArrayList<>();
        Long code2 = 0L;
        Long code3 = 0L;
        Long code4 = 0L;
        if (StrUtil.isBlank(uid)) {
            //如果为空，则查询所有用户
            userInfos = userInfoApi.findAll();
            userIds = CollUtil.getFieldValues(userInfos, "userId", Long.class);

            code2 = publishApi.countByStatus(2);
            code3 = publishApi.countByStatus(3);
            code4 = publishApi.countByStatus(4);
        } else {
            //单独查询某一个用户
            UserInfo userInfo = userInfoApi.findUserInfoByUserId(Convert.toLong(uid));
            userInfos.add(userInfo);
            userIds.add(userInfo.getUserId());
            code2 = publishApi.countOneByStatus(uid, 2);
            code3 = publishApi.countOneByStatus(uid, 3);
            code4 = publishApi.countOneByStatus(uid, 4);
        }


        Title title1 = new Title("全部", "1", code2 + code3 + code4);
        Title title2 = new Title("待审核", "2", code2);
        Title title3 = new Title("已通过", "3", code3);
        Title title4 = new Title("已拒绝", "4", code4);

        List<Title> titleList = new ArrayList<>();
        titleList.add(title1);
        titleList.add(title2);
        titleList.add(title3);
        titleList.add(title4);


        if ("-1".equals(ed)) {
            ed = Convert.toStr(System.currentTimeMillis());
        }

        List<Publish> publishes = null;
        if ("1".equals(state)) {
            //状态唯一，表示要查询用户的所有状态信息
            publishes = publishApi.queryPublishByUid(userIds, page, pagesize, Convert.toLong(sd), Convert.toLong(ed));
        } else {
            //单独对某一页查询
            publishes = publishApi.queryPublishByUid(userIds, page, pagesize, Convert.toLong(sd), Convert.toLong(ed), Convert.toInt(state));
        }

        if (ObjectUtil.isNull(publishes)) {
            //如果为空，则没发过朋友圈
            return new PageResult(page, pagesize, code2 + code3 + code4, ListUtil.empty(), titleList);
        }
        Map<Long, UserInfo> map = CollUtil.fieldValueMap(userInfos, "userId");

        List<ManageVo> voList = new ArrayList<>();
        for (Publish publish : publishes) {
            //封装vo对象
            ObjectId id = publish.getId();
            Long userId = publish.getUserId();
            UserInfo userInfo = map.get(userId);
            ManageVo manageVo = new ManageVo();
            manageVo.setReportCount(0L);
            manageVo.setForwardingCount(0L);
            manageVo.setNickname(userInfo.getNickName());
            manageVo.setUserLogo(userInfo.getLogo());
            manageVo.setId(Convert.toStr(id));
            manageVo.setUserId(userId);
            manageVo.setCreateDate(publish.getCreated());
            manageVo.setText(publish.getText());
            manageVo.setState(Convert.toStr(publish.getStatus()));
            manageVo.setLikeCount(commentApi.queryCommentCount(Convert.toStr(id), 1));
            manageVo.setCommentCount(commentApi.queryCommentCount(Convert.toStr(id), 2));
            manageVo.setMedias(publish.getMedias());
            voList.add(manageVo);
        }

        return new PageResult(page, pagesize, code2 + code3 + code4, voList, titleList);
    }

    public boolean messagesPass(String[] publishIds) {

        if (ObjectUtil.isNotNull(publishIds)) {

            for (String id : publishIds) {

                Integer status = publishApi.queryStatus(id);

                if (status == 3) {
                    //审核完调用该方法，把数据库的status更新
                    publishApi.setAuditing(new ObjectId(id), UserThreadLocal.getUserId(), 2);
                }
            }
        }
        return true;
    }

    public void messagesReject(String[] publishIds) {
        if (ObjectUtil.isNotNull(publishIds)) {

            for (String id : publishIds) {

                Integer status = publishApi.queryStatus(id);

                if (status == 3) {
                    //审核完调用该方法，把数据库的status更新
                    publishApi.setAuditing(new ObjectId(id), UserThreadLocal.getUserId(), 4);
                }
            }
        }
    }

    public void messagesRevocation(String[] publishIds) {
        if (ObjectUtil.isNotNull(publishIds)) {

            for (String id : publishIds) {

                Integer status = publishApi.queryStatus(id);

                if (status == 2) {
                    //审核完调用该方法，把数据库的status更新
                    publishApi.setAuditing(new ObjectId(id), UserThreadLocal.getUserId(), 4);
                } else if (status == 4) {
                    //审核完调用该方法，把数据库的status更新
                    publishApi.setAuditing(new ObjectId(id), UserThreadLocal.getUserId(), 2);
                }
            }
        }
    }

    public ManageTopVo findOneMessages(String publishId) {
        Publish publish = publishApi.queryPublishById(publishId);

        UserInfo info = userInfoApi.findUserInfoByUserId(publish.getUserId());
        ManageVo manageVo = getManageVo(publish.getUserId(), publish, info);

        ManageTopVo manageTopVo = BeanUtil.toBean(manageVo, ManageTopVo.class);

        int topState = publish.getTopState();

        manageTopVo.setTopState(topState);
        return manageTopVo;
    }

    public void messagesTop(String publishId) {
        publishApi.setTop(new ObjectId(publishId), 2);
    }

    public void messagesUntop(String publishId) {
        publishApi.setTop(new ObjectId(publishId), 1);
    }
}
